/*
 * AIStateManager.cpp
 *
 *  Created on: Sep 1, 2017
 *      Author: gaoyi
 */

#include "AIStateManager.h"

#include "BornState/BornState.h"
#include "NoneState/NoneState.h"
#include "PatrolState/PatrolState.h"

AIStateManager::AIStateManager(void)
{
    // 需要确保插入顺序和AI State定义顺序一致
    m_pState.push_back(std::shared_ptr<AIBaseState>(new NoneState));
    m_pState.push_back(std::shared_ptr<AIBaseState>(new BornState));
    m_pState.push_back(std::shared_ptr<AIBaseState>(new PatrolState));
//    m_pState.push_back(std::shared_ptr<AIBaseState>(new FollowState));
//    m_pState.push_back(std::shared_ptr<AIBaseState>(new RestState));
//    m_pState.push_back(std::shared_ptr<AIBaseState>(new PreFightState));
//    m_pState.push_back(std::shared_ptr<AIBaseState>(new FightState));
//    m_pState.push_back(std::shared_ptr<AIBaseState>(new DeadState));
//    m_pState.push_back(std::shared_ptr<AIBaseState>(new EndFightState));
//    m_pState.push_back(std::shared_ptr<AIBaseState>(new BackState));
//    m_pState.push_back(std::shared_ptr<AIBaseState>(new RoamState));
}

AIStateManager::~AIStateManager(void)
{
	m_pState.clear();
}

AIBaseState* AIStateManager::GetState(Creature* pCreature, AIData* pAIData)
{
	if (pCreature == nullptr || pAIData == nullptr) return nullptr;

	int nCurState = pAIData->GetCurState();
	if (nCurState < 0 || nCurState >= AI_STATE_MAX || nCurState >= (int)m_pState.size()) return nullptr;

	return m_pState[nCurState].get();
}

bool AIStateManager::ChangeState(Creature* pCreature, AIData* pAIData,const AIStateEnum eState, const int controller)
{
    AIBaseState* pState = GetState(pCreature, pAIData);
    if (!pState)
    {
        return false;
    }

    if (!pState->CanChangeState(pCreature, pAIData, eState))
    {
        return false;
    }

    pState->LeaveState(pCreature, pAIData);

    int nCurState = pAIData->GetCurState();

    pAIData->SetPreState(nCurState);
    pAIData->SetCurState(eState);

    pState = GetState(pCreature, pAIData);
    if (!pState || !pState->EnterState(pCreature, pAIData))
    {
        return false;
    }

    return true;
}


